package base.thread_demo.demo21;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicReference;

/**
 * AtomicReference原子引用保护String类型共享数据
 *
 */
public class Demo01 {
    private static final Logger log = LoggerFactory.getLogger(Demo01.class);

    public static void main(String[] args) {
        test1();
    }

    public static void test1() {
        AtomicReference<String> ref = new AtomicReference<>("A");

        /*
         * 演示在test1方法中修改ref原子引用，但中途被其他线程进行了ABA修改，
         * 就是其他线程最终还原了现场，AtomicReference这个API是识别不了的。
         */
        other(ref);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.info(ref.get());
        log.info("change A -> C is {}",ref.compareAndSet(ref.get(), "C"));

    }

    public static void other(AtomicReference<String> ref) {
        new Thread(()->{
            log.info(ref.get());
            log.info("change A -> B is {}", ref.compareAndSet(ref.get(), "B"));
        },"t1").start();

        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            log.info(ref.get());
            log.info("change B -> A is {}", ref.compareAndSet(ref.get(), "A"));
        },"t2").start();
    }

}

